package com.jfinal.bbsapp.common.kit;

public class SnowFlakeUtil {
	private static SnowFlake snowFlake = new SnowFlake(1, 1);
    public static void main(String[] args) {
        long orderid = snowFlake.nextId();
        
        //long snowId = 146030458632700928L;
        long ctime = System.currentTimeMillis();
        System.out.println(ctime);
        System.out.println(orderid);
        System.out.println(SnowFlakeUtil.datetimeBySnowId(orderid));
        //System.out.println(SnowFlakeUtil.datetimeByTimestamp(timestamp(orderid)));
       // System.out.println(SnowFlakeUtil.timestamp(orderid));
        //System.out.println(SnowFlakeUtil.toBinaryStringWithSplitSymbol(6671529211465728L));
       //System.out.println(new Date(1587952216515L));
    }

    /**
     * timestamp bit长度
     */
    public static int TIMESTAMP_BIT = 41;
    /**
     * 数据中心bit长度
     */
    public static int DATA_CENTER_BIT = 5;
    /**
     * 机器bit长度
     */
    public static int WORKER_BIT = 5;
    /**
     * 每ms序号bit长度
     */
    public static int SEQ_BIT = 12;
    /**
     * 算法的总bit长度
     */
    public static int FULL_BIT = 64;
    /**
     * 起始时间戳 2020-04-09 00:00:00
     */
    public static long EPOCH = 1566316801000L;

    /**
     * 以二进制位带-分隔符形式返回id
     *
     * @param snowId
     * @return
     */
    static String toBinaryStringWithSplitSymbol(long snowId) {

        char[] bId = Long.toBinaryString(snowId).toCharArray();
        StringBuilder sb = new StringBuilder();
        //标志位
        sb.append("0").append('-');

        //时间戳
        int timestamp = bId.length - (WORKER_BIT + DATA_CENTER_BIT + SEQ_BIT);
        int zero = TIMESTAMP_BIT - timestamp;
        //时间戳前面补全0
        for (int i = 0; i < zero; i++) {
            sb.append(0);
        }
        for (int i = 0; i < timestamp; i++) {
            sb.append(bId[i]);
        }
        sb.append('-');

        //data center + work
        int workLength = WORKER_BIT + DATA_CENTER_BIT;
        for (int i = timestamp; i < timestamp + workLength; i++) {
            sb.append(bId[i]);
        }
        sb.append('-');
        //num seq
        for (int i = timestamp + workLength; i < bId.length; i++) {
            sb.append(bId[i]);
        }
        return sb.toString();
    }

    /**
     * 从雪花id中计算出规定起始时间戳的时间戳
     * 起始时间戳见EPOCH字段
     *
     * @param snowId 雪花算法生成的id
     * @return
     */
    public static long timestamp(long snowId) {
        String bid = Long.toBinaryString(snowId);
        int timestamp = bid.length() - (WORKER_BIT + DATA_CENTER_BIT + SEQ_BIT);
        String substring = bid.substring(0, timestamp);
        return Long.parseUnsignedLong(substring, 2);
    }

    /**
     * 根据雪花id的时间戳，计算真实时间戳，从1970.。。开始
     *
     * @param timestamp 雪花算法的时间戳
     * @return
     */
    public static long datetimeByTimestamp(long timestamp) {
        return timestamp + EPOCH;
    }

    /**
     * 根据雪花id输出真实时间戳，从19.。。
     *
     * @param snowId
     * @return
     */
    public static long datetimeBySnowId(long snowId) {
        return timestamp(snowId) + EPOCH;
    }

}